package com.ruoyi.web.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.ijpay.core.enums.SignType;
import com.ijpay.core.enums.TradeType;
import com.ijpay.core.kit.IpKit;
import com.ijpay.core.kit.WxPayKit;
import com.ijpay.wxpay.WxPayApi;
import com.ijpay.wxpay.WxPayApiConfig;
import com.ijpay.wxpay.WxPayApiConfigKit;
import com.ijpay.wxpay.model.UnifiedOrderModel;
import com.jfinal.kit.StrKit;
import com.ruoyi.common.business.entity.YytMember;
import com.ruoyi.common.oms.entity.YytOmsCartItem;
import com.ruoyi.common.oms.entity.YytOmsOrder;
import com.ruoyi.common.oms.entity.YytOmsOrderItem;
import com.ruoyi.common.oms.entity.YytOmsPaymentInfo;
import com.ruoyi.common.oms.service.YytOmsCartItemService;
import com.ruoyi.common.oms.service.YytOmsOrderService;
import com.ruoyi.common.oms.service.YytOmsPaymentInfoService;
import com.ruoyi.common.pms.entity.YytMaaCraftsman;
import com.ruoyi.common.pms.entity.YytMaaSubscribeVisit;
import com.ruoyi.common.pms.service.YytMaaCraftsmanService;
import com.ruoyi.common.pms.service.YytMaaSubscribeVisitService;
import com.ruoyi.common.sms.entity.YytSmsCouponHistory;
import com.ruoyi.common.sms.service.YytSmsCouponHistoryService;
import com.ruoyi.utils.CommonUtils;
import com.ruoyi.utils.LoginUtils;
import com.ruoyi.utils.RedisService;
import com.ruoyi.utils.ResponseResult;
import com.ruoyi.vo.SubscribeStoreVo;
import com.ruoyi.vo.WxPayBean;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.pms.entity.YytMaaSubscribeStore;
import com.ruoyi.common.pms.service.YytMaaSubscribeStoreService;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
* <p>
    * 预约到店表 前端控制器
    * </p>
*
* @author MrPing
* @since 2022-03-14
*/
@RestController
@RequestMapping("/subscribe")
public class YytMaaSubscribeStoreController {

    public static Cache<String, String> applyCache = CacheBuilder.newBuilder().maximumSize(600).expireAfterWrite(60, TimeUnit.MINUTES).build();

    @Autowired
    private RedisService redisService;
    @Autowired
    private YytOmsOrderService yytOmsOrderService;
    @Autowired
    private YytOmsCartItemService yytOmsCartItemService;

    @Autowired
    private YytMaaSubscribeStoreService yytMaaSubscribeStoreService;

    @Autowired
    private YytMaaSubscribeVisitService yytMaaSubscribeVisitService;

    @Autowired
    private YytMaaCraftsmanService yytMaaCraftsmanService;

    @Autowired
    private YytSmsCouponHistoryService yytSmsCouponHistoryService;

    @Autowired
    private YytOmsPaymentInfoService yytOmsPaymentInfoService;
    @Autowired
    private WxPayBean wxPayBean;

    private String notifyUrl;
    private String refundNotifyUrl;

    public WxPayApiConfig getApiConfig() {
        WxPayApiConfig apiConfig;

        try {
            apiConfig = WxPayApiConfigKit.getApiConfig(wxPayBean.getAppId());
        } catch (Exception e) {
            System.out.println("wxPayBean.getCertPath():" + wxPayBean.getCertPath());
            apiConfig = WxPayApiConfig.builder()
                    .appId(wxPayBean.getAppId())
                    .mchId(wxPayBean.getMchId())
                    .partnerKey(wxPayBean.getPartnerKey())
                    .certPath(wxPayBean.getCertPath())
                    .domain(wxPayBean.getDomain())
                    .build();
        }
        notifyUrl = apiConfig.getDomain().concat("/order/payNotify");
//        refundNotifyUrl = apiConfig.getDomain().concat("/order/refundNotify");
        return apiConfig;
    }

    /**
     * 项目预约
     * @param subscribeStoreVo
     * @return
     */
    @PostMapping("/createSubscribeStore")
    public ResponseResult createSubscribeStore(@RequestBody SubscribeStoreVo subscribeStoreVo, HttpServletRequest request){
        YytMember loginUser = LoginUtils.getLoginUser(redisService);
        YytOmsOrder yytOmsOrder = subscribeStoreVo.getYytOmsOrder();
        yytOmsOrder.setMemberId(loginUser.getId());
        yytOmsOrder.setMemberUsername(loginUser.getUsername());
        yytOmsOrderService.createOrder(yytOmsOrder);

        YytMaaSubscribeStore yytMaaSubscribeStore = new YytMaaSubscribeStore();
        BeanUtils.copyProperties(subscribeStoreVo, yytMaaSubscribeStore);
        System.out.println(yytMaaSubscribeStore);
        yytMaaSubscribeStore.setOrderId(yytOmsOrder.getId());
        yytMaaSubscribeStore.setCheckoutCode(yytOmsOrder.getId());
        yytMaaSubscribeStoreService.save(yytMaaSubscribeStore);

        // 移除该用户的购物车对应商品
        List<String> skuIdList = new ArrayList<>();
        for (YytOmsOrderItem item : yytOmsOrder.getItemList()) {
            skuIdList.add(item.getSkuId());
        }
        yytOmsCartItemService.remove(new LambdaQueryWrapper<YytOmsCartItem>()
                .in(YytOmsCartItem::getProductSkuId, skuIdList).eq(YytOmsCartItem::getMemberId, loginUser.getId()));
        // redis放入订单 半小时未支付关闭订单
        redisService.put("order:" + yytOmsOrder.getOrderSn(), CommonUtils.serialize(yytOmsOrder), 1800L);

        String orderSn = yytOmsOrder.getOrderSn();
        String orderId = yytOmsOrder.getId();
        String totalAmount = yytOmsOrder.getTotalAmount().toString();

        BigDecimal bFee = new BigDecimal(totalAmount).multiply(new BigDecimal(100));
        if (loginUser.getWechatId().equals("opTmV5ZC8x9hPKsCVcPauTOw4L5Q")){
            bFee = BigDecimal.valueOf(1);
        }
        String openid = loginUser.getWechatId();

        String ip = IpKit.getRealIp(request);
        if (StrKit.isBlank(ip)) {
            ip = "127.0.0.1";
        }
        WxPayApiConfigKit.putApiConfig(getApiConfig());
        WxPayApiConfig wxPayApiConfig = WxPayApiConfigKit.getWxPayApiConfig();
        String tradeno = WxPayKit.generateStr();
        Map<String, String> params = UnifiedOrderModel
                .builder()
                .appid(wxPayApiConfig.getAppId())
                .mch_id(wxPayApiConfig.getMchId())
                .nonce_str(WxPayKit.generateStr())
                .body("御医堂收款")
                .attach("御医堂")
                .out_trade_no(tradeno)
                .total_fee(bFee.intValue() + "")
//                .total_fee("1")
                .spbill_create_ip(ip)
                .notify_url(notifyUrl)
                .trade_type(TradeType.JSAPI.getTradeType())
                .openid(openid)
                .build()
                .createSign(wxPayApiConfig.getPartnerKey(), SignType.HMACSHA256);

        String xmlResult = WxPayApi.pushOrder(false, params);
        System.out.println(xmlResult);

//        log.info(xmlResult);
        Map<String, String> result = WxPayKit.xmlToMap(xmlResult);

        String returnCode = result.get("return_code");
        String returnMsg = result.get("return_msg");

        if (!WxPayKit.codeIsOk(returnCode)) {
//            return new AjaxResult().addError();
            return ResponseResult.failure(returnMsg);
        }
        String resultCode = result.get("result_code");
        if (!WxPayKit.codeIsOk(resultCode)) {
            return ResponseResult.failure(returnMsg);

        }
        // 以下字段在 return_code 和 result_code 都为 SUCCESS 的时候有返回
        String prepayId = result.get("prepay_id");

        Map<String, String> packageParams = WxPayKit.miniAppPrepayIdCreateSign(wxPayApiConfig.getAppId(), prepayId,
                wxPayApiConfig.getPartnerKey(), SignType.HMACSHA256);
        String jsonStr = JSON.toJSONString(packageParams);
        System.out.println("jsonStr" + jsonStr);
//        log.info("小程序支付的参数:" + jsonStr);
        applyCache.put(tradeno, orderId + "#" + orderSn + "#" + totalAmount);
        JSONObject object = new JSONObject();
        JSONObject object1 = new JSONObject();
        YytOmsPaymentInfo yytOmsPaymentInfo = new YytOmsPaymentInfo();
        yytOmsPaymentInfo.setOrderId(orderId);
        yytOmsPaymentInfo.setOrderSn(orderSn);
        yytOmsPaymentInfo.setAlipayTradeNo(tradeno);
        yytOmsPaymentInfo.setTotalAmount(new BigDecimal(totalAmount));
//        yytOmsPaymentInfo.setTotalAmount(new BigDecimal("0.01"));
        yytOmsPaymentInfo.setSubject("亿器互联");
        yytOmsPaymentInfo.setPaymentStatus("0");
        yytOmsPaymentInfo.setCreateTime(java.time.LocalDateTime.now());
        yytOmsPaymentInfo.setCallbackContent(jsonStr);
        yytOmsPaymentInfo.setCallbackTime(java.time.LocalDateTime.now());
        yytOmsPaymentInfoService.save(yytOmsPaymentInfo);
        if(StringUtils.isNotBlank(yytOmsOrder.getCouponId()) && StringUtils.isNotBlank(String.valueOf(yytOmsOrder.getCouponAmount()))){
            object.put("couponId", yytOmsOrder.getCouponId());
            object.put("couponAmount", yytOmsOrder.getCouponAmount());
            String[] strings = yytOmsOrder.getCouponId().split(",");
            for (String ids : strings){
                UpdateWrapper<YytSmsCouponHistory> wrapper = new UpdateWrapper<>();
                wrapper.eq("id", ids).set("use_mode", 1);
                yytSmsCouponHistoryService.update(wrapper);
            }
        }
        object.put("orderId", orderId);
        object.put("orderSn", orderSn);
        object.put("memberId", loginUser.getId());
        object.put("out_trade_no", tradeno);
        object.put("id", yytOmsOrder.getId());
        object1.put("user", object);
        object1.put("jsonStr", jsonStr);


        return ResponseResult.success(object1);
    }


    /**
     * 获取我的预约订单
     * @param wxId
     * @return
     */
    @GetMapping("/getMyDataList")
    public ResponseResult getMyDataList(@RequestParam("wxId") String wxId,
                                        @RequestParam("status") String status
                                        ){
        String orderId = null;
        return ResponseResult.success(yytMaaSubscribeStoreService.getOrderOrProduct(wxId, status, orderId));
    }

    /**
     * 通过订单id 获取预约服务详情
     * @param wxId
     * @param orderId
     * @return
     */
    @GetMapping("/orderByInfoData")
    public ResponseResult orderByInfoData(@RequestParam("wxId") String wxId,
                                          @RequestParam("orderId") String orderId
                                            ){

        String status = null;
        return ResponseResult.success(yytMaaSubscribeStoreService.getOrderOrProduct(wxId, status, orderId));
    }


    /**
     * 绑定手艺人
     * @param orderId
     * @return
     */
    @GetMapping("/bindOrderServerUser")
    public ResponseResult bindOrderServerUser(@RequestParam("orderId") String orderId, @RequestParam("userId") String userId){
        UpdateWrapper<YytMaaSubscribeStore> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("order_id", orderId).set("service_user_id", userId);
        yytMaaSubscribeStoreService.update(updateWrapper);
        UpdateWrapper<YytOmsOrder> orderUpdateWrapper = new UpdateWrapper<>();
        orderUpdateWrapper.eq("id", orderId).set("dispose_status", "1");
        boolean update = yytOmsOrderService.update(orderUpdateWrapper);
        return ResponseResult.success(update);
    }

}
